package com.tomorrowshine.voice.speaknative;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;

import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
 
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
 
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.util.ResourceUtil;
 
/**
 * Created by cheng.li on 2015/7/14.
 * site:tomorrowshine.com
 */
public class Speak  extends CordovaPlugin {
    SpeechSynthesizer mTts=null;
    private CallbackContext callbackContext=null;
    private static boolean slienceFlag=false;
 
    public boolean execute(String action, JSONArray args, CallbackContext callback)
            throws JSONException {
        this.callbackContext = callback;
        if (action.equals("init")) {
            JSONObject parms = args.getJSONObject(0);
            this.setParms(parms);
        }else if(action.equals("speak")){
            JSONObject utterance = args.getJSONObject(0);
            String text = utterance.getString("text");
            Log.d("=========", "开始语音播放" + text);
            mTts.startSpeaking(text, mSynListener);
        }else if(action.equals("cancel")){
            mTts.destroy();
        }else if(action.equals("silence")) {
            this.silence(args.getJSONObject(0));
        }else if(action.equals("setSystemVolume")) {
            this.setSystemVolume(args.getDouble(0));
        }else if(action.equals("getSystemVolume")) {
            callbackContext.success(this.getSystemVolume());
        }else{
            return false;
        }
        return true;
    }
    public void setParms(JSONObject parms){
         Context context=this.cordova.getActivity();
         SpeechUtility.createUtility(context, SpeechConstant.APPID + "=53e4cc8f,engine_mode=auto");
        //1.创建 SpeechSynthesizer 对象, 第二个参数：本地合成时传 InitListener
        mTts= SpeechSynthesizer.createSynthesizer(context, mTtsInitListener);
        //2.合成参数设置，详见《科大讯飞MSC API手册(Android)》SpeechSynthesizer 类
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD); //设置云端
        //设置发音人资源路径
        //mTts.setParameter(ResourceUtil.TTS_RES_PATH,getResourcePath(context));
        String VOICE_NAME="xiaoyan";
        String PITCH="50";
        String SPEED="50";
        String VOLUME="80";
        String KEY_REQUEST_FOCUS="true";
        try {
            VOICE_NAME=parms.getString("VOICE_NAME");
            SPEED=parms.getString("SPEED");
            PITCH=parms.getString("PITCH");
            VOLUME=parms.getString("VOLUME");
            KEY_REQUEST_FOCUS=parms.getString("KEY_REQUEST_FOCUS");
        }catch (JSONException e){
 
        }
        mTts.setParameter(SpeechConstant.VOICE_NAME, VOICE_NAME);//设置发音人
        //设置引擎类型为本地
//        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
        //设置合成音调
        mTts.setParameter(SpeechConstant.PITCH,PITCH);
        mTts.setParameter(SpeechConstant.SPEED, SPEED);//设置语速
        mTts.setParameter(SpeechConstant.VOLUME, VOLUME);//设置音量，范围 0~100
        //设置播放器音频流类型
        mTts.setParameter(SpeechConstant.STREAM_TYPE,"3");
        // 设置播放合成音频打断音乐播放，默认为true
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS,KEY_REQUEST_FOCUS);
        //如果不需要保存合成音频，注释该行代码
        //保存在 SD 卡需要在 AndroidManifest.xml 添加写 SD 卡权限
        //mTts.setParameter(SpeechConstant.PARAMS,"tts_audio_path="+ Environment.getExternalStorageDirectory()+"/testcc.pcm");
        callbackContext.success("NativeSpeak init success currentVolume:"+getSystemVolume());
    }
    //获取发音人资源路径
    private String getResourcePath(Context context){
        StringBuffer tempBuffer = new StringBuffer();
        //合成通用资源
        tempBuffer.append(ResourceUtil.generateResourcePath(context, ResourceUtil.RESOURCE_TYPE.assets, "tts/common.jet"));
        tempBuffer.append(";");
        //发音人资源
        tempBuffer.append(ResourceUtil.generateResourcePath(context, ResourceUtil.RESOURCE_TYPE.assets, "tts/xiaoyan.jet"));
        return tempBuffer.toString();
    }
    /**
     * 初始化监听。
     */
    private InitListener mTtsInitListener = new InitListener() {
        @Override
        public void onInit(int code) {
            if (code != ErrorCode.SUCCESS) {
            } else {
                //开始合成
                // 初始化成功，之后可以调用startSpeaking方法
                // 注：有的开发者在onCreate方法中创建完合成对象之后马上就调用startSpeaking进行合成，
                // 正确的做法是将onCreate中的startSpeaking调用移至这里
            }
        }
    };
 
    //合成监听器
    private SynthesizerListener mSynListener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {
        }
        @Override
        public void onSpeakPaused() {
 
        }
        @Override
        public void onSpeakResumed() {
        }
        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos,
                                     String info) {
            // 合成进度
        }
        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            // 播放进度
            if(slienceFlag)setSystemVolume(0);
        }
        @Override
        public void onCompleted(SpeechError error) {
            // 播放完成
            fireEndEvent(callbackContext,"end");
        }
        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
        }
    };
    private void fireEndEvent(CallbackContext callbackContext,String flag) {
        JSONObject event = new JSONObject();
        try {
            event.put("type",flag);
        } catch (JSONException e) {
            // this will never happen
        }
        callbackContext.success(event);
        callbackContext.error(event);
    }
    public void silence(JSONObject parms) {
        AudioManager am = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);
        try {
           if(parms.getBoolean("silence")){
               am.setStreamVolume(AudioManager.STREAM_MUSIC,0,0);
               slienceFlag=true;
           }else{
               am.setStreamVolume(AudioManager.STREAM_MUSIC,parms.getInt("systemVolume"),0);
               slienceFlag=false;
           }
        }catch (JSONException e){
 
        }
    }
    public void setSystemVolume(double volume) {
        AudioManager am = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);
        am.setStreamVolume(
                AudioManager.STREAM_MUSIC,
                (int) (am.getStreamMaxVolume(AudioManager.STREAM_MUSIC) * volume),
                0);
 
    }
    public int getSystemVolume(){
        AudioManager am = (AudioManager) this.cordova.getActivity().getSystemService(Context.AUDIO_SERVICE);
        int  currentVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
        return currentVolume;
    }
 
}

